bitkeeper revision 1.576 (3facdede5nZbIb45xqApby8e8U5CQA)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 8 Nov 2003 12:17:34 +0000 (12:17 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 8 Nov 2003 12:17:34 +0000 (12:17 +0000)
xi_save_linux.c, xi_restore_linux.c, Makefile:
  Suspend/resume now uses zlib to reduce the state file size.

tools/internal/Makefile
tools/internal/xi_restore_linux.c
tools/internal/xi_save_linux.c

index 83e23d2aa3801d806a487639549cef701facb776..03a36dc27722952ccf5c1def6bff569405317639 100644 (file)
@@ -12,7 +12,15 @@ TARGETS += xi_phys_grant xi_list xi_save_linux xi_restore_linux
 TARGETS += xi_sched_global xi_sched_domain xi_usage xi_vif_params
 INSTALL  = $(TARGETS) xi_vifinit xi_helper
 
-all: $(TARGETS)
+all: check-for-zlib $(TARGETS)
+
+check-for-zlib:
+       @if [ ! -e /usr/include/zlib.h ]; then \
+       echo "***********************************************************"; \
+       echo "ERROR: install zlib header files (http://www.gzip.org/zlib)"; \
+       echo "***********************************************************"; \
+       false; \
+       fi
 
 install: all
        mkdir -p ../../../install/bin
@@ -31,6 +39,9 @@ rpm: all
        mv staging/i386/*.rpm .
        rm -rf staging
 
+xi_save_linux xi_restore_linux: %: %.c $(HDRS) Makefile
+       $(CC) $(CFLAGS) -lz -o $@ $<
+
 %: %.c $(HDRS) Makefile
        $(CC) $(CFLAGS) -o $@ $<
 
index 8ccd145d93e01832e470f14eb326cc9bda14a61b..fa1d3e5c55b4bc5633b14435ac094db043084c4b 100644 (file)
@@ -10,6 +10,8 @@
 #include "mem_defs.h"
 #include <asm-xeno/suspend.h>
 
+#include <zlib.h>
+
 static char *argv0 = "internal_restore_linux";
 
 /* A table mapping each PFN to its new MFN. */
@@ -120,10 +122,10 @@ static void unmap_pfn(void *vaddr)
     (void)munmap(vaddr, PAGE_SIZE);
 }
 
-static int checked_read(int fd, void *buf, size_t count)
+static int checked_read(gzFile fd, void *buf, size_t count)
 {
     int rc;
-    while ( ((rc = read(fd, buf, count)) == -1) && (errno == EINTR) )
+    while ( ((rc = gzread(fd, buf, count)) == -1) && (errno == EINTR) )
         continue;
     return rc == count;
 }
@@ -164,8 +166,9 @@ int main(int argc, char **argv)
     suspend_record_t *p_srec;
 
     /* The name and descriptor of the file that we are reading from. */
-    char *filename;
-    int fd;
+    char  *filename;
+    int    fd;
+    gzFile gfd;
 
     if ( argv[0] != NULL ) 
         argv0 = argv[0];
@@ -183,19 +186,26 @@ int main(int argc, char **argv)
         return 1;
     }
 
+    if ( (gfd = gzdopen(fd, "rb")) == NULL )
+    {
+        ERROR("Could not allocate decompression state for state file");
+        close(fd);
+        return 1;
+    }
+
     /* Start writing out the saved-domain record. */
-    if ( !checked_read(fd, signature, 16) ||
+    if ( !checked_read(gfd, signature, 16) ||
          (memcmp(signature, "XenoLinuxSuspend", 16) != 0) )
     {
         ERROR("Unrecognised state format -- no signature found");
         goto out;
     }
 
-    if ( !checked_read(fd, name,                  sizeof(name)) ||
-         !checked_read(fd, &nr_pfns,              sizeof(unsigned long)) ||
-         !checked_read(fd, &ctxt,                 sizeof(ctxt)) ||
-         !checked_read(fd, shared_info,           PAGE_SIZE) ||
-         !checked_read(fd, pfn_to_mfn_frame_list, PAGE_SIZE) )
+    if ( !checked_read(gfd, name,                  sizeof(name)) ||
+         !checked_read(gfd, &nr_pfns,              sizeof(unsigned long)) ||
+         !checked_read(gfd, &ctxt,                 sizeof(ctxt)) ||
+         !checked_read(gfd, shared_info,           PAGE_SIZE) ||
+         !checked_read(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) )
     {
         ERROR("Error when reading from state file");
         goto out;
@@ -222,7 +232,7 @@ int main(int argc, char **argv)
     pfn_to_mfn_table = calloc(1, 4 * nr_pfns);
     pfn_type         = calloc(1, 4 * nr_pfns);    
 
-    if ( !checked_read(fd, pfn_type, 4 * nr_pfns) )
+    if ( !checked_read(gfd, pfn_type, 4 * nr_pfns) )
     {
         ERROR("Error when reading from state file");
         goto out;
@@ -282,7 +292,7 @@ int main(int argc, char **argv)
 
         mfn = pfn_to_mfn_table[i];
 
-        if ( !checked_read(fd, page, PAGE_SIZE) )
+        if ( !checked_read(gfd, page, PAGE_SIZE) )
         {
             ERROR("Error when reading from state file");
             goto out;
@@ -482,5 +492,7 @@ int main(int argc, char **argv)
         printf("DOM=%ld\n", dom);
     }
 
+    gzclose(gfd);
+
     return !!rc;
 }
index bbefaa1fb3e2dd879539edb8caefedc05980cb0b..3170664b7497b829c6dce549e359b617f337d9ee 100644 (file)
@@ -10,6 +10,8 @@
 #include "mem_defs.h"
 #include <asm-xeno/suspend.h>
 
+#include <zlib.h>
+
 static char *argv0 = "internal_save_linux";
 
 /* A table mapping each PFN to its current MFN. */
@@ -94,10 +96,10 @@ static unsigned int get_pfn_type(unsigned long mfn)
     return op.u.getpageframeinfo.type;
 }
 
-static int checked_write(int fd, const void *buf, size_t count)
+static int checked_write(gzFile fd, void *buf, size_t count)
 {
     int rc;
-    while ( ((rc = write(fd, buf, count)) == -1) && (errno = EINTR) )
+    while ( ((rc = gzwrite(fd, buf, count)) == -1) && (errno = EINTR) )
         continue;
     return rc == count;
 }
@@ -136,8 +138,9 @@ int main(int argc, char **argv)
     suspend_record_t *p_srec, srec;
 
     /* The name and descriptor of the file that we are writing to. */
-    char *filename;
-    int fd;
+    char  *filename;
+    int    fd;
+    gzFile gfd;
 
     if ( argv[0] != NULL ) 
         argv0 = argv[0];
@@ -162,6 +165,17 @@ int main(int argc, char **argv)
         return 1;
     }
 
+    /*
+     * Compression rate 1: we want speed over compression. We're mainly going
+     * for those zero pages, after all.
+     */
+    if ( (gfd = gzdopen(fd, "wb1")) == NULL )
+    {
+        ERROR("Could not allocate compression state for state file");
+        close(fd);
+        return 1;
+    }
+
     /* Ensure that the domain exists, and that it is stopped. */
     for ( ; ; )
     {
@@ -314,13 +328,13 @@ int main(int argc, char **argv)
 
     /* Start writing out the saved-domain record. */
     ppage = map_pfn(shared_info_frame);
-    if ( !checked_write(fd, "XenoLinuxSuspend",    16) ||
-         !checked_write(fd, name,                  sizeof(name)) ||
-         !checked_write(fd, &srec.nr_pfns,         sizeof(unsigned long)) ||
-         !checked_write(fd, &ctxt,                 sizeof(ctxt)) ||
-         !checked_write(fd, ppage,                 PAGE_SIZE) ||
-         !checked_write(fd, pfn_to_mfn_frame_list, PAGE_SIZE) ||
-         !checked_write(fd, pfn_type,              4 * srec.nr_pfns) )
+    if ( !checked_write(gfd, "XenoLinuxSuspend",    16) ||
+         !checked_write(gfd, name,                  sizeof(name)) ||
+         !checked_write(gfd, &srec.nr_pfns,         sizeof(unsigned long)) ||
+         !checked_write(gfd, &ctxt,                 sizeof(ctxt)) ||
+         !checked_write(gfd, ppage,                 PAGE_SIZE) ||
+         !checked_write(gfd, pfn_to_mfn_frame_list, PAGE_SIZE) ||
+         !checked_write(gfd, pfn_type,              4 * srec.nr_pfns) )
     {
         ERROR("Error when writing to state file");
         goto out;
@@ -365,7 +379,7 @@ int main(int argc, char **argv)
             }
         }
 
-        if ( !checked_write(fd, page, PAGE_SIZE) )
+        if ( !checked_write(gfd, page, PAGE_SIZE) )
         {
             ERROR("Error when writing to state file");
             goto out;
@@ -386,6 +400,8 @@ int main(int argc, char **argv)
         (void)do_dom0_op(&op);
     }
 
+    gzclose(gfd);
+    
     /* On error, make sure the file is deleted. */
     if ( rc != 0 )
         unlink(filename);